start: function start(
    tag, //标签名称
    attrs,   //标签属性
    unary  // 如果不是单标签则为真
) {
    var ns = (currentParent && currentParent.ns) ||
        platformGetTagNamespace(tag);

    if (isIE && ns === 'svg') {
        attrs = guardIESVGBug(attrs);
    }
    var element = createASTElement(tag, attrs, currentParent);
    if (ns) { 
        element.ns = ns;
    }


    for (var i = 0; i < preTransforms.length; i++) {
        element = preTransforms[i](element, options) || element;
    }

    if (!inVPre) { //如果  标签 没有 v-pre 指令
        processPre(element);    //检查标签是否有v-pre 指令 含有 v-pre 指令的标签里面的指令则不会被编译
        if (element.pre) { //标记 标签是否还有 v-pre 指令
            inVPre = true; //如果标签有v-pre 指令 则标记为true
        }
    }
    if (platformIsPreTag(element.tag)) { //  判断标签是否是pre 如果是则返回真
        inPre = true;
    }
    if (inVPre) { //如果含有 v-pre 指令
        //浅拷贝属性 把虚拟dom的attrsList拷贝到attrs中,如果没有pre块，标记plain为true
        processRawAttrs(element);
    } else if (!element.processed) {
        // structural directives  指令
        //判断获取v-for属性是否存在如果有则转义 v-for指令 把for，alias，iterator1，iterator2属性添加到虚拟dom中
        processFor(element);
        //获取v-if属性，为el虚拟dom添加 v-if，v-eles，v-else-if 属性
        processIf(element);
        //获取v-once 指令属性，如果有有该属性 为虚拟dom标签 标记事件 只触发一次则销毁
        processOnce(element);
        // element-scope stuff

        //校验属性的值，为el添加muted， events，nativeEvents，directives，  key， ref，slotName或者slotScope或者slot，component或者inlineTemplate 标志 属性
        processElement(element, options);
    }

    //检查根约束 根节点不能是slot或者template标签，并且不能含有v-for 属性
    function checkRootConstraints(el) {
        {
            if (el.tag === 'slot' || el.tag === 'template') {
                warnOnce(
                    "Cannot use <" + (el.tag) + "> as component root element because it may " +
                    'contain multiple nodes.'
                );
            }
            if (el.attrsMap.hasOwnProperty('v-for')) {
                warnOnce(
                    'Cannot use v-for on stateful component root element because ' +
                    'it renders multiple elements.'
                );
            }
        }
    }

    // tree management
    if (!root) {
        root = element;
        //检查根约束 根节点不能是slot或者template标签，并且不能含有v-for 属性
        checkRootConstraints(root);
    } else if (!stack.length) {
        // allow root elements with v-if, v-else-if and v-else
        //允许根元素带有v-if、v-else-if和v-else
        if (root.if && (element.elseif || element.else)) {
            checkRootConstraints(element);//检查根约束 根节点不能是slot或者template标签，并且不能含有v-for 属性

            //为if指令添加标记
            addIfCondition(
                root, //根节点
                {
                    exp: element.elseif, //view 试图中的elseif 属性
                    block: element //当前的虚拟dom
                }
            );
        } else {
            warnOnce(
                "Component template should contain exactly one root element. " +
                "If you are using v-if on multiple elements, " +
                "use v-else-if to chain them instead."
            );
        }
    }
    //如果currentParent父节点存在。并且element.forbidden不存在
    if (
        currentParent &&
        !element.forbidden   //如果是style或者是是script 标签并且type属性不存在 或者存在并且是javascript 属性 的时候返回真
    ) {
        if (element.elseif || element.else) { //如果有elseif或者else属性的时候
            //找到上一个兄弟节点，如果上一个兄弟节点是if，则下一个兄弟节点则是elseif
            processIfConditions(element, currentParent);
        } else if (element.slotScope) { // scoped slot 作用域的槽

            currentParent.plain = false;
            //获取slotTarget作用域标签，如果获取不到则定义为default
            var name = element.slotTarget || '"default"';
            (currentParent.scopedSlots || (currentParent.scopedSlots = {}))[name] = element;
        } else {
            //如果父节点存在currentParent则在父节点添加一个子节点，并且
            currentParent.children.push(element);
            //当前节点上添加parent属性
            element.parent = currentParent;
        }
    }


    if (!unary) {
        currentParent = element;
        //为parse函数 stack标签堆栈 添加一个标签
        stack.push(element);
    } else {
        //克隆节点
        closeElement(element);

    }
}